#include"Epollevent.h"
#include"sys/epoll.h"
#include <utility>
using std::make_pair;
Epollevent::Epollevent(Acceptor &accptor)
: _epfd(createEpollFd())
, _evtlist(1024)
, _isLooping(false)
, _accept(accptor)
{
    //将listenfd放在红黑树上进行监听
    //看有没有新的连接请求上来
    //问题：如何获取listenfd（socket）
    //解决方案：可以在Acceptor类中设置fd()函数，
    //进而获取listenfd
    addEpollreadfd(_accept.fd());
}

//创建epfd
//创建文件描述符_epfd
int Epollevent::createEpollFd()
{
    int fd = ::epoll_create1(0);
    if(fd < 0)
    {
        perror("epoll_create1");
        return fd;
    }

    return fd;
}


void Epollevent:: Loop(){
    _isLooping = true;
    while(_isLooping)
    {
        waitEpollFd();
    }
}
void Epollevent::waitEpollFd()//封装epoll_wait的函数
{
    int nready = 0;
    do
    {
        nready = epoll_wait(_epfd, &*_evtlist.begin(), _evtlist.size(), 3000);
    }while(-1 == nready && errno == EINTR);

    if(-1 == nready)
    {
        perror("waitEpollFd");
        return;
    }
    else if(0 == nready)
    {
        cout << ">>epoll_wait timeout!!!" << endl;
    }
    else
    {
        //如果客户端的连接请求非常的多，多到马上要超过1024了，
        //所以_evtList需要进行扩容，而现在没有自动扩容的能力
        if(nready == (int)_evtlist.size())
        {
            _evtlist.resize(2 * nready);
        }

        for(int idx = 0; idx < nready; ++idx)
        {
            int fd = _evtlist[idx].data.fd;
            //有新的连接请求
            if(fd == _accept.fd())
            {
                if(_evtlist[idx].events & EPOLLIN)
                {
                    //处理新的连接
                    handlNewConnection();
                }
            }
            else
            {
                if(_evtlist[idx].events & EPOLLIN)
                {
                    //处理消息的收发
                    handlNewMessage(fd);
                }

            }
        }
    }
}
void Epollevent::unLoop(){
    _isLooping = false;
}
void Epollevent::addEpollreadfd(int fd){
    
}
void Epollevent::deleEpollwritefd(int fd){
    
}


void Epollevent::setNewConneciton(TcpConnectionCallback _cb){

}
void Epollevent::setNewMessage(TcpConnectionCallback _cb){

}
void Epollevent::setNewClose(TcpConnectionCallback _cb){

}
void Epollevent::handlNewConnection(){
    int newNetfd = _accept.accept();
    if(newNetfd < 0){
        cout<<"newNetfd is Fail"<<endl;
        return;
    }
    //只是监听fd
    addEpollreadfd(newNetfd);
    //建立连接
    TcpConnectionPtr con(new Tcpconnection(newNetfd));
    //建立连接，将三个半事件 进行注册
    con->setNewConneciton(_onNewConnection);
    con->setNewMessage(_onNewMessage);
    con->setNewClose(_onNewClose);

    //此时是建立了连接，所以执行连接事件
    //存放键值对
    _cons.insert(make_pair(newNetfd,con));
    con->handlNewConnection();
}
//这里要fd 是为了找到对应的tcp连接，然后进行操作
void Epollevent::handlNewMessage(int fd){

}
void Epollevent::handlNeclose(){

}

